// NeL - MMORPG Framework <http://dev.ryzom.com/projects/nel/>
// Copyright (C) 2010  Winch Gate Property Limited
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as
// published by the Free Software Foundation, either version 3 of the
// License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program.  If not, see <http://www.gnu.org/licenses/>.

#ifdef HAVE_CONFIG_H
#include "config.h"
#endif // HAVE_CONFIG_H

#ifndef SNOWBALLS_CONFIG
#define SNOWBALLS_CONFIG ""
#endif // SNOWBALLS_CONFIG

#ifndef SNOWBALLS_LOGS
#define SNOWBALLS_LOGS ""
#endif // SNOWBALLS_LOGS

#include <map>
#include <utility>
#include <game_share/object_pool.h>

#include "frontend_service.h"
#include "session_mgr.h"
#include "client_mgr.h"
#include "msg_fes.h"
#include "msg_fes_broadcast.h"
#include "msg_client.h"
#include "msg_ls.h"
#include "msg_zs.h"
#include "msg_egs.h"

#ifdef NL_OS_WINDOWS
#include <Windows.h>
#endif

using namespace NLMISC;
using namespace NLNET;
using namespace FES;

//NLNET::CMessage msgout;
NLNET::CCallbackServer *Clients = 0;

NLMISC::CVariable<bool>		AcceptClientsAtStartup("FS", "AcceptClientsAtStartup", "Set Frontend Accept mode (1=accept clients, 0=patching mode)", false, 0, true);


/**
 *   from client
 */

NLNET::TCallbackItem ClientCallbackArray[] =
{
	{ "LOGIN",		cbLogin          },
	{ "HB",			cbHeartBeat      },
	{ "CT",			cbCreateTeam     },
	{ "B",			cbBuild          },	
	{ "RB",			cbRemoveBuild    },
	{ "U",			cbUpBuild        },
};

/**
 * Contains *all* callbacks from the shard
 */
NLNET::TUnifiedCallbackItem CallbackArray[] =
{
	{ "UI",					cbUserInfo},			//	from EGS
	{ "T2C",				cbTransport2Client},	//	to client   from EGS && ZS
//	{ "GET_FES_INFO",		cbGetFesInfo},
	{ "GET_SESSION",		cbClientGetSession},	//	from LS
	{ "LOGOUT",				cbClientLogout},		//	from ZS
//	{ "INIT_PLAYER",		cbInitPlayer},
	{ "LOAD_SCENE",			cbClientLoadScene},
	{ "PLAYER_NULL",		cbClientPlayerIsNull},
	{ "ERR",				cbErr},

	
	
	
};


//
///****************************************************************************
// * CFrontEndService
// ****************************************************************************/
void CFrontEndService::init()
{
	// set accept mode
	//AcceptClients = AcceptClientsAtStartup.get();

	_inetIP	                     = IService::getInstance ()->ConfigFile.getVar ("INetIP").asString();
	_inetPort                    = IService::getInstance ()->ConfigFile.getVar ("INetPort").asInt();
	uint32 playerMax             = IService::getInstance ()->ConfigFile.getVar ("ClientMax").asInt();
	uint32 playerTimeOut         = IService::getInstance ()->ConfigFile.getVar ("ClientTimeOut").asInt();
	uint32 playerUpdateInterval  = IService::getInstance ()->ConfigFile.getVar ("ClientUpdateInterval").asInt();

	//_asyncPlayerCount            = IService::getInstance ()->ConfigFile.getVar ("AsyncLoginPlayerCountInterval").asInt();

	SessionMgr.init();

	//NLNET::CUnifiedNetwork::getInstance()->setServiceUpCallback("WS", cbWSConnection, NULL);
	CUnifiedNetwork::getInstance ()->setServiceUpCallback ("LS", cbLSConnection, NULL);

	Clients = new NLNET::CCallbackServer ();
	nlassert (Clients != 0);
	Clients->addCallbackArray (ClientCallbackArray, sizeof(ClientCallbackArray)/sizeof(ClientCallbackArray[0]));

	Clients->setConnectionCallback ( onConnectionClient, NULL );
	Clients->setDisconnectionCallback ( onDisconnectClient, NULL );
	Clients->init (_inetPort);

	//CCookieMgr::getInstance().init( cookieMax, cookieTimeOut, cookieUpdateInterval );
	ClientMgr.init( Clients );

	// Connect the frontend to the login system
	//NLNET::CLoginServer::init( *Clients, NULL/*onConnectionClient*/ );



	///*
	// * Set the callback function when the Chat service reconnect to the
	// * frontend
	// */
	//CUnifiedNetwork::getInstance ()->setServiceUpCallback ("CHAT", onReconnectChat, 0);

	///*
	// * Set the callback function when the Chat service disconnect from
	// * frontend
	// */
	//CUnifiedNetwork::getInstance ()->setServiceDownCallback ("CHAT", onDisconnectChat, 0);
}

bool CFrontEndService::update()
{
	// Manage messages from clients
	Clients->update ();

	_CurrTicks = CTime::getLocalTime();

	SessionMgr.update( _CurrTicks );
	ClientMgr.update( _CurrTicks );

	return true;
}

void CFrontEndService::release()
{
	delete Clients;
	Clients = NULL;
}

/****************************************************************************   
 * SNOWBALLS FRONTEND SERVICE MAIN Function
 *
 * This call create a main function for a service:
 *
 *    - based on the "CFrontEndService" class
 *    - having the short name "FS"
 *    - having the long name "frontend_service"
 *    - listening on the port "0" (dynamically determined)
 *    - and shard callback set to "CallbackArray"
 *
 ****************************************************************************/
NLNET_SERVICE_MAIN (CFrontEndService, "FS", "frontend_service", 0, CallbackArray, SNOWBALLS_CONFIG, SNOWBALLS_LOGS)


/* end of file */
